/*
 * sqlite.c
 *
 *  Project Name: ratbox-monitor
 *    Created on: Dec 11, 2010
 *        Author: Daniel J Reidy <dubkat@ratbox.org>
 *            Id: $Id: database.c 50 2012-04-04 03:46:50Z dubkat $
 */

#include <string.h>
#include "ratbox_lib.h"
#include "database.h"
#include "settings.h"
#include "common.h"
#include "logger.h"

#define SZ 1024

enum VarType
{
	INT,
	STR
};

struct db_table
{
	const char *key;	// database key
	char *value;		// database value
	const char *desc;	// hooman description of the value
	enum VarType vtype;	// what type of value, string or int
	enum YesNo ask;		// ask for user input at startup?
};

struct key_val
{
	char *key;
	char *val;
};

/* this table holds all the appropriate, valid settings for the database,
 * and are required for the bot to function
 */
/* *INDENT-OFF* */
struct db_table settings_table[] = {
        /* KEY       VAL          DESCRIPTION                       TYPE   ASK  */
	{ "NICK",    "",          "Monitors IRC Nickname",          STR,   YES },
	{ "ALTNICK", "",          "Alternate Nickname",             STR,   YES },
	{ "USERNAME", "",         "Username, if not using identd.", STR,   YES },
	{ "GECOS",   "ratbox-monitor", "Gecos",                     STR,    NO },
	{ "AWAY",    "I am a bot, go away!", "Auto-Away Message",   STR,   YES },
	{ "SERVER",  "127.0.0.1", "IRC Server IP",                  STR,   YES },
	{ "SERVERPASS",   "",     "IRC Server Password",            STR,   YES },
	{ "OPERNAME",    "",      "Monitor Oper Nick",              STR,   YES },
	{ "OPERPASS",    "",      "Monitor Oper Pass",              STR,   YES },
	{ "VHOST",   "0.0.0.0",   "Vhost to use.",                  STR,   YES },
	{ "SSL",     "N",          "Connect via SSL?",              INT,   YES },
	{ "EXTRA_UMODE", "+I",    "Bot will choose what it's best UMODES are, anything extra?", STR, YES },
	{ NULL,      NULL,        NULL,                    0,     0   }
};
/* *INDENT-ON* */

struct db_chan
{
	char *channel;
	char *key;
	int rep_rbl;
	int rep_drone;
};

struct db_chan channels_table[] = {
	{"", "", 0, 0},
	{NULL, NULL, 0, 0}

};

struct key_val stable[1024] = { };

void
database_open(const char *path)
{
	int rc;

	if(database != NULL)
		return;

	rc = sqlite3_open_v2(path, &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
	if(rc != SQLITE_OK)
	{
		logger(CRIT, "database_open: ERROR: Can't open sqlite3 database at %s", path);
		exit(EXIT_FAILURE);
	}
}

int
database_close(void)
{
	int r = 0;
	if(database)
		r = sqlite3_close(database);
	return r;
}

/* blindly execute an sql statement, with no regard of it's success */
static void
database_exec(const char *sql)
{
	sqlite3_stmt *stmt;

	logger(DEBUG, "database_exec: SQL: %s", sql);
	if(sqlite3_prepare_v2(database, sql, -1, &stmt, 0) == SQLITE_OK)
	{
		sqlite3_step(stmt);
		sqlite3_finalize(stmt);
	}
	else
		logger(DEBUG, "database_exec: SQL FAILURE: %s", sql);
}

void
database_setup(void)
{
	int i;
	const char *setup_sql[] = {
		"CREATE TABLE users (nick_id INTEGER, nick TEXT, flags INTEGER);",
		"CREATE TABLE users_host (nick_id INTEGER, host TEXT);",
		"CREATE TABLE settings (setting TEXT, value TEXT);",
		"CREATE TABLE channels (channel TEXT, key TEXT, report_rbl INTEGER, report_drone INTEGER);",
		"CREATE TABLE regexps  (regex_id INTEGER, regex TEXT, action TEXT, action_time TEXT, users_id INTEGER, added INTEGER, hitcount INTEGER);",
		NULL,
	};

	for(i = 0; setup_sql[i] != NULL; i++)
		database_exec(setup_sql[i]);
}


void
database_setup_wizard(void)
{
	char in[SZ];
	char sql[SZ];
	int i;
	struct db_table *tb;
	struct key_val *kv;
	
	const char *banner[4] = {
		"             __   __                                        __ __              \n",
		".----.---.-.|  |_|  |--.-----.--.--. .--------.-----.-----.|__|  |_.-----.----.\n",
		"|   _|  _  ||   _|  _  |  _  |_   _| |        |  _  |     ||  |   _|  _  |   _|\n",
		"|__| |___._||____|_____|_____|__.__| |__|__|__|_____|__|__||__|____|_____|__|  \n"
	};
	
	fprintf(stdout, "*******************************************************************************\n");

	for(i=0; i < 4; i++ ) fprintf(stdout, banner[i] );
	
	fprintf(stdout, "               %s-%s Setup Wizard\n\n", PACKAGE_NAME, PACKAGE_VERSION);
	fprintf(stdout, "*******************************************************************************\n");
	fprintf(stdout, 
		"I will attempt to help you setup your monitor for the first time.\n"
		"If you make a mistake, hit Control+C (^C) to exit, and start again with the --setup switch.\n"
		"I will only ask you enough questions to get your bot onto IRC, and into your control channel.\n"
		"All further settings can be configured by you with <botnick> set <field> <value>\n"
		"To see all currently configured settings, issue <botnick> settings\n"
	);
	fprintf(stdout, "*******************************************************************************\n");

	for(i = 0;; i++)
	{
		tb = &settings_table[i];
		kv = &stable[i];

		if(tb->key == NULL)
		{
			kv->key = NULL;
			kv->val = NULL;
			break;
		}

		fprintf(stdout, "%s [%s]: ", tb->desc, tb->value);
		fetch_input(in);

		kv->key = (char *)malloc(sizeof(tb->key));
		if(kv->key == NULL)
			exit(1);

		strcpy(kv->key, tb->key);

		//if ( tb->vtype == INT )
		//  kv->val = atoi(in);
		//else

		if(strlen(in) > 0)
		{
			if(!(kv->val = (char *)malloc(sizeof(in))))
				exit(1);
			
			if( tb->vtype == INT ) {
				if ( *in == 'y' || *in == 'Y' )
					kv->val = "1";
				else
					kv->val = "0";
			}
			else
				strcpy(kv->val, in);
		}
		else
		{
			if(!(kv->val = (char *)malloc(sizeof(tb->value))))
				exit(1);

			strcpy(kv->val, tb->value);
		}
	}

	for(i = 0;; i++)
	{
		
		kv = &stable[i];
		if(kv->key == NULL)
			break;

		if ( database ) {
			rb_snprintf(sql, SZ, "INSERT INTO settings (setting,value) VALUES ('%s','%s');", kv->key, kv->val);
			database_exec(sql);
		} else {
			logger(CRIT, "ERROR: setup wizard lost connection to the database.");
			exit(EXIT_FAILURE);
		}
		
		rb_free(kv->key);
		rb_free(kv->val);
	}
	
	/* TODO we still need to ask for an inital channel and inital ADMIN */
	
	kv = NULL;
	tb = NULL;
}


static void
fetch_input(char *line)
{
	char *p;
	p = fgets(line, SZ, stdin);
	if(p == NULL)
	{
		fprintf(stderr, "ERROR: out of buffer space\n");
		exit(EXIT_FAILURE);
	}
	size_t l = strlen(line) - 1;
	if(line[l] == '\n')
		line[l] = '\0';
}

int
hashdb_regexps(void)
{




	return 0;
}
